package com.zhitong.money.services;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.zhitong.money.entity.CheckTime;
import com.zhitong.money.entity.Dept;
import com.zhitong.money.exception.AddException;
import com.zhitong.money.exception.DeleteException;
import com.zhitong.money.exception.RepeatException;
import com.zhitong.money.exception.UpdateException;
import com.zhitong.money.mapper.CheckMapper;
import com.zhitong.money.mapper.DeptMapper;
import com.zhitong.money.mapper.EmployeeMapper;
import com.zhitong.money.mapper.PositionMapper;
import com.zhitong.money.services.api.ICheckService;
import com.zhitong.money.util.DateUtil;

import lombok.extern.slf4j.Slf4j;
import net.sf.jasperreports.engine.JasperExportManager;
import net.sf.jasperreports.engine.JasperFillManager;
import net.sf.jasperreports.engine.JasperPrint;

import net.sf.jasperreports.engine.data.JRBeanCollectionDataSource;
import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import javax.sql.DataSource;
import java.io.File;
import java.io.FileOutputStream;
import java.net.URLEncoder;
import java.sql.Connection;
import java.text.DecimalFormat;
import java.util.*;


@Slf4j
@Service
public class CheckService implements ICheckService {

    @Autowired
    private CheckMapper mapper;

    @Autowired
    private PositionMapper positionMapper;

    @Autowired
    private EmployeeMapper employeeMapper;

    @Autowired
    private DataSource dataSource;

    @Autowired
    private DeptMapper deptMapper;


    @Override
    public List<CheckTime> findAllCheck() throws Exception {
        List<CheckTime> allCheckTime = mapper.findAllCheck();
        return allCheckTime;
    }

//    @Override
//    public List<CheckTime> findCheckByTid(String tid) throws Exception {
//        return null;
//    }

    @Override
    public List<CheckTime> findCheckByMap(Map<String, Object> map) throws Exception {
            List<CheckTime> checkTimeByMap = mapper.findCheckByMap(map);
            return checkTimeByMap;
    }

    @Override
    public PageInfo findAllCheckByPage(Map<String,Object> map) throws Exception {
        int pageNum=map.containsKey("pageNum")?(int)map.get("pageNum"):1;
        int pageSize=map.containsKey("pageSize")?(int)map.get("pageSize"):5;
        PageHelper.startPage(pageNum,pageSize);
        List<CheckTime> allCheckTime = mapper.findCheckByMap(map);
        PageInfo pageInfo=new PageInfo(allCheckTime);
        return pageInfo;
    }

    @Override
    public CheckTime findCheckById(String id) throws Exception {
        CheckTime checkTime = mapper.findCheckById(id);
        if (checkTime==null){
            throw new NullPointerException("findCheckById:查询为空!");
        }
        return checkTime;
    }

    /**
     *@Author: AndyZhang
     *@Description 添加一次考勤
     *@param
     *@return
     *@Date: 11:22 2021/2/5
     */
    @Override
    public void addCheck(CheckTime checkTime) throws Exception {
        Map<String,Object> map=new HashMap<>();
        map.put("tid", checkTime.getTid());
        map.put("date", checkTime.getDate());
        List<CheckTime> checkTimeByMap = mapper.findCheckByMap(map);
        if (!checkTimeByMap.isEmpty()){
            throw new RepeatException("该考勤重复!");
        }
        try {
            mapper.addCheck(checkTime);
        } catch (Exception e) {
            throw  new AddException("addCheck:添加失败!"+e.getMessage());
        }
    }

    /**
     *@Author: AndyZhang
     *@Description 自定义添加考勤
     *@param
     *@return
     *@Date: 11:22 2021/2/5
     */
    @Override
    public void addCheck(Map<String, Object> map) throws Exception {
        String did=map.get("did").toString();
        Date date= DateUtil.StrToDate(map.get("date").toString(),DateUtil.FORMAT_DATE_CHECK);
        List<String> idsByDid = positionMapper.findIdsByDid(did);
        if (idsByDid==null || idsByDid.isEmpty()){
            throw new NullPointerException("addCheck:职位查询为空!");
        }
        List<String> tellIdsByPids = employeeMapper.findTellIdsByPids(idsByDid);
        if (idsByDid==null || idsByDid.isEmpty()){
            throw new NullPointerException("addCheck:员工查询为空!");
        }
        try {
            CheckTime checkTime=new CheckTime();
            for (String tid:tellIdsByPids) {
                checkTime.setId(UUID.randomUUID().toString().replace("-",""));
                checkTime.setTid(tid);
                checkTime.setDate(date);
                checkTime.setStatus("00");
                mapper.addCheck(checkTime);
            }
        } catch (Exception e) {
            throw  new AddException("addCheck:添加失败!"+e.getMessage());
        }

    }

    @Override
    public void updateCheck(CheckTime checkTime) throws Exception {
        try {
            mapper.updateCheck(checkTime);
        } catch (Exception e) {
            throw  new UpdateException("updateCheck:修改失败!"+e.getMessage());
        }
    }

    @Override
    public void delCheck(String id) throws Exception {
        try {
            mapper.delCheck(id);
        } catch (Exception e) {
            throw new DeleteException("delCheck:删除失败!"+e.getMessage());
        }
    }

    @Override
    public void delCheckByIds(List<String> ids) throws Exception {
        try {
            mapper.delCheckByIds(ids);
        } catch (Exception e) {
            throw new DeleteException("delCheckByIds:删除失败!"+e.getMessage());
        }
    }

    /**
     *@Author: AndyZhang
     *@Description 导出excel表格
     *@param
     *@return
     *@Date: 9:25 2021/2/7
     */
    @Override
    public void exportChecks(Map<String, Object> map, HttpServletResponse response) throws Exception {
//       找到数据
        String[] titles = {"员工编号","员工姓名","签到日期","签到时间","签退时间","签到状态","签到结果"};
        List<CheckTime> checkByMap = mapper.findCheckByMap(map);
        HSSFWorkbook sheets = new HSSFWorkbook();
        HSSFSheet sheet = sheets.createSheet("考勤");
        //设置标题样式
        HSSFCellStyle cellStyle = sheets.createCellStyle();
        //水平垂直居中
        cellStyle.setAlignment(HorizontalAlignment.CENTER);
        cellStyle.setVerticalAlignment(cellStyle.getVerticalAlignmentEnum().CENTER);
        //字体
        HSSFFont font = sheets.createFont();
        font.setFontName("华文行楷");//设置字体名称
        font.setFontHeightInPoints((short)12);//设置字号
        font.setBold(true);
        cellStyle.setFont(font);
        //设置标题
        HSSFRow row = sheet.createRow(0);
        for (int i = 0; i < titles.length; i++) {
            //设置宽度
            sheet.setColumnWidth(i,15*256);
            HSSFCell cell = row.createCell(i);
            cell.setCellValue(titles[i]);
            cell.setCellStyle(cellStyle);
        }
        //设置内容
        CheckTime checkTime = new CheckTime();
        for (int i = 0; i < checkByMap.size(); i++) {
            row = sheet.createRow(i+1);
            checkTime=checkByMap.get(i);
            row.createCell(0).setCellValue(checkTime.getTid());
            row.createCell(1).setCellValue(checkTime.getName());
            row.createCell(2).setCellValue(DateUtil.dateToStr(checkTime.getDate(),DateUtil.FORMAT_DATE_CHECK));
            row.createCell(3).setCellValue(checkTime.getStartTime()==null?"":DateUtil.dataTimeToStr(checkTime.getStartTime(),DateUtil.FORMAT_DATE_Time));
            row.createCell(4).setCellValue(checkTime.getEndTime()==null?"":DateUtil.dataTimeToStr(checkTime.getEndTime(),DateUtil.FORMAT_DATE_Time));
            row.createCell(5).setCellValue(checkTime.getStatus().equals("00")?"未签到":"已签到");
            row.createCell(6).setCellValue(getResult(checkTime.getResult()==null?"":checkTime.getResult()));
        }
        response.setCharacterEncoding("UTF-8");
        response.setHeader("Content-type", "application/vnd.ms-excel");
        response.setHeader("Content-Disposition", "attachment;filename=" + "check.xls");
        // 响应类型,编码
        response.setContentType("application/octet-stream;charset=UTF-8");
        ServletOutputStream outputStream = response.getOutputStream();
        sheets.write(outputStream);
        outputStream.flush();
        outputStream.close();
    }

    /**
     *@Author: AndyZhang
     *@Description 一个月的迟到时间总和
     *@param
     *@return
     *@Date: 16:01 2021/2/20
     */
    @Override
    public String lateForMonth(String tid, int year,int m) throws Exception {
        double lateTime=0;

        //获取本月分的考勤
        List<CheckTime> checkByMonth = mapper.findCheckByMonth(tid,"00",m,year);
        List<CheckTime> lateAndEarly = mapper.findCheckByMonth(tid, "06", m, year);
        if (lateAndEarly!=null && !lateAndEarly.isEmpty()){
           checkByMonth.addAll(lateAndEarly);
        }

        if (checkByMonth!=null && !checkByMonth.isEmpty()){

            //获得该员工部门
            Dept deptByTid = deptMapper.findDeptByTid(tid);

            for (CheckTime time : checkByMonth) {
                long second = time.getStartTime().getEpochSecond() - deptByTid.getStartTime().getEpochSecond();
                if (second>0){
                    double hour = (double)second/3600;
                    lateTime+=hour;
                }
            }
        }
        DecimalFormat df=new DecimalFormat("#0.00");
        return df.format(lateTime);
    }

    /**
     *@Author: AndyZhang
     *@Description 一个月的早退时间总和
     *@param
     *@return
     *@Date: 16:02 2021/2/20
     */
    @Override
    public String earlyForMonth(String tid, int year,int m) throws Exception {
        double eralyTime=0;

        //获取本月分的考勤
        List<CheckTime> checkByMonth = mapper.findCheckByMonth(tid,"02",m,year);
        List<CheckTime> lateAndEarly = mapper.findCheckByMonth(tid, "06", m, year);
        if (lateAndEarly!=null && !lateAndEarly.isEmpty()){
            checkByMonth.addAll(lateAndEarly);
        }
        if (checkByMonth!=null && !checkByMonth.isEmpty()){
            //获得该员工部门
            Dept deptByTid = deptMapper.findDeptByTid(tid);

            for (CheckTime time : checkByMonth) {
                long second =  deptByTid.getEndTime().getEpochSecond()-time.getEndTime().getEpochSecond();
                if (second>0){
                    double hour = (double)second/3600;
                    eralyTime+=hour;
                }
            }
        }
        DecimalFormat df=new DecimalFormat("#0.00");
        return df.format(eralyTime);
    }

    /**
     *@Author: AndyZhang
     *@Description 一个月的缺勤总和
     *@param
     *@return
     *@Date: 16:03 2021/2/22
     */
    @Override
    public double absenceForMonth(String tid, int year,int m) throws Exception {
        double a=0;
        //获取缺勤的考勤
        List<CheckTime> checkByMonth = mapper.findCheckByMonth(tid,"03",m,year);
        a+=checkByMonth.size();
        //获取未签退的考勤
        List<CheckTime> fd = mapper.findCheckByMonth(tid,"05",m,year);
        if (!fd.isEmpty()){
            a+=fd.size()/2;
        }

        return a;
    }

    /**
     *@Author: AndyZhang
     *@Description 一个月的请假总和
     *@param
     *@return
     *@Date: 16:03 2021/2/22
     */
    @Override
    public double leaveForMonth(String tid, int year, int m) throws Exception {
        List<CheckTime> checkByMonth = mapper.findCheckByMonth(tid, "04", m, year);
        return checkByMonth.size();
    }


    private  String getResult(String val){
        switch (val){
            case "00":
                return "迟到";
            case "01":
                return "正常";
            case "02":
                return "早退";
            case "03":
                return "缺席";
            case "04":
                return "请假";
            case "05":
                return "未签退";
            case "06":
                return "迟到且早退";
            default:
                return "未签到";

        }
    }
}
